/**
 * 
 */
package com.cea.papyrus.diagram.component.editpart;

/**
 * @author al090761
 *
 */
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.tools.CellEditorLocator;
import org.eclipse.gef.tools.DirectEditManager;
import org.eclipse.uml2.uml.Artifact;
import org.eclipse.uml2.uml.Dependency;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ElementImport;
import org.eclipse.uml2.uml.Generalization;
import org.eclipse.uml2.uml.Manifestation;
import org.eclipse.uml2.uml.NamedElement;

import com.cea.papyrus.core.PapyrusMessages;
import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.core.directedit.ILabelControler;
import com.cea.papyrus.core.directedit.LabelCellEditorLocator;
import com.cea.papyrus.core.directedit.LabelControler;
import com.cea.papyrus.core.directedit.LabelDirectEditManager;
import com.cea.papyrus.core.directedit.PropertyAccessor;
import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.editor.mouseoveraction.ActionHandleManager;
import com.cea.papyrus.core.editpart.ContainerHighlightEditPolicy;
import com.cea.papyrus.core.editpart.ContainerWithSemanticEditPart;
import com.cea.papyrus.core.editpart.GraphNodeEditPolicy;
import com.cea.papyrus.core.figures.IconFigure;
import com.cea.papyrus.core.figures.NodeFigure;
import com.cea.papyrus.core.ui.dialogs.PapyrusMessageDialog;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagram.component.figure.ArtifactFigure;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;



/**
 * Manages the model of an artifact in a ComponentDiagram
 * 
 * @author Gilles Cannenterre
 * @since 15 janv. 07
 */

public class ArtifactEditPart extends ContainerWithSemanticEditPart {

		
		/**
		 * Debug channel for edit parts.
		 */
		private int channel = 202;
		
		/**
		 * Manager for editing nodename.
		 */
		protected DirectEditManager manager;
		
		/**
		 * 
		 * 
		 * @param modelManager 
		 * @param graphNode 
		 */
		public ArtifactEditPart(GraphNode graphNode,ModelManager modelManager) {
			super(graphNode,modelManager);
		}

		/* (non-Javadoc)
		 * @see com.cea.papyrus.common.editpart.GraphNodeWithSemanticEditPart#createFigure()
		 */
		/**
		 * 
		 * 
		 * @return 
		 */
		@Override
		protected IFigure createFigure() {
			// Force initialization of the manager when figure has changed
			manager = null;
			// Try to get figure from ContainerWithSemanticEditPart
			IFigure fig = super.createFigure();
			if (fig != null) {
				return fig;
			}
			// Else
			return new ArtifactFigure("artifact");				
		}

		/* (non-Javadoc)
		 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getContentPane()
		 */
		/**
		 * 
		 * 
		 * @return 
		 */
		@Override
		public IFigure getContentPane() {
			if (getFigure() instanceof ArtifactFigure) {
				return ((ArtifactFigure) getFigure()).getContentPane();

			} else {
				// Figure is a shape
				return getFigure();
			}
		}

		/**
		 * Returns the Name Label of this edit part.
		 * 
		 * @return Label
		 */
		protected Label getNameLabel() {
			IFigure fig = getFigure();
			if (fig instanceof IconFigure) {
				return (Label) fig;
			} else if (fig instanceof ArtifactFigure) {
				return ((ArtifactFigure) fig).getNameLabel();
			} else {
				Debug.debug(this, "ArtifactEditPart::getNameLabel() : Unknown Figure type.", channel);
				return null;
			}
		}

		/**
		 * the direct edit mechanism requires the edit part to handle the direct edit
		 * request.
		 * 
		 * @param req the request that called the direct edit.
		 */
		public void performDirectEdit(Request req) {
			initLabelEditManager();
			manager.show();
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.gef.editparts.AbstractEditPart#performRequest(org.eclipse.gef.Request)
		 */
		/**
		 * 
		 * 
		 * @param request 
		 */
		@Override
		public void performRequest(Request request){
			if (RequestConstants.REQ_DIRECT_EDIT.equals(request.getType())) {
				performDirectEdit(request);
			}
		}
		
		/*
		 * (non-Javadoc)
		 * @see com.cea.papyrus.common.editpart.ContainerEditPart#createEditPolicies()
		 */
		/**
		 * 
		 */
		@Override
		protected void createEditPolicies(){
			super.createEditPolicies();
			installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE,new ContainerHighlightEditPolicy());
			installEditPolicy(EditPolicy.LAYOUT_ROLE, new ArtifactLayoutEditPolicy((XYLayout) getContentPane().getLayoutManager()));
			installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new GraphNodeEditPolicy() );
			// Deals with specific actions on node
			installActionHandle();
		}

		/**
		 * Refresh visuals.
		 */
		@Override
		protected void refreshVisuals() {
			Debug.debug(this, "refreshVisuals()", channel);
		
			Dimension size = getGraphNode().getSize();
			Point p = getGraphNode().getPosition();
			Rectangle r = new Rectangle(p, size);
	
			IFigure fig = getFigure();
		
			// Classifier
			if (fig instanceof IconFigure) {
				IconFigure icf = (IconFigure) getFigure();
				icf.setName(((NamedElement) getUmlElement()).getName());
			} else {
				Artifact currentArtifact = getUmlElement();
				com.cea.papyrus.umlutils.Element currentElement = new com.cea.papyrus.umlutils.Element(getUmlElement());
				((NodeFigure) fig).refreshColors(getGraphNode());
				((NodeFigure) fig).refreshPresentation(getPresentation(),currentArtifact, getGraphNode());
				
				boolean hasIcon = currentElement.hasIcon();
				boolean hasShape = currentElement.hasShape();
			
				((NodeFigure) fig).refreshStereotypes(((NodeFigure) fig).stereotypesLabel(this), getPresentation(), hasIcon, hasShape);
				((NodeFigure) fig).setName(currentArtifact.getName());
		
				// qualifiedName
				GraphNode gp= (GraphNode) getGraphNode().getContainer();
				((NodeFigure) fig).refreshQualifiedName(gp, getGraphNode(), getUmlElement());
			}  
		
			((GraphicalEditPart) getParent()).setLayoutConstraint(this, fig, r);
		}

		/* (non-Javadoc)
		 * @see com.cea.papyrus.common.editpart.GraphNodeWithSemanticEditPart#getUmlElement()
		 */
		/**
		 * 
		 * 
		 * @return 
		 */
		@Override
		public Artifact getUmlElement() {
			Element e=((Uml1SemanticModelBridge)getGraphNode().getSemanticModel()).getElement();
			// Case of element import
			if(e instanceof ElementImport){
				return (Artifact)((ElementImport) e).getImportedElement();
			}
			// This is a simple Artifact
			return (Artifact)e;
		}

		/**
		 * Install Action handles for this editPart.
		 * Use same toolEntries than in palette
		 */
		protected void installActionHandle()
		{
			// Install mouse hover
			ActionHandleManager actionMngr = new ActionHandleManager(this);	
			// Create a toolbar of actions.
			PaletteDrawer entries = new PaletteDrawer("creation tool");
		
			try{
				entries.add(PapyrusPlugin.creationToolFactory.getConnectionCreationToolEntry(
						PapyrusMessages.AddManifestationCommand_Label
						, PapyrusMessages.AddManifestationCommand_Description
						, Manifestation.class
						, null));
				entries.add(PapyrusPlugin.creationToolFactory.getConnectionCreationToolEntry(
						PapyrusMessages.AddDependencyCommand_Label
						, PapyrusMessages.AddDependencyCommand_Description
						, Dependency.class
						, null));
				entries.add(PapyrusPlugin.creationToolFactory.getConnectionCreationToolEntry(
						PapyrusMessages.AddGeneralizationCommand_Label
						, PapyrusMessages.AddGeneralizationCommand_Description
						, Generalization.class
						, null));
			}
			catch (Exception e) {
				PapyrusMessageDialog.display(e.getMessage(), e);
			}
			actionMngr.addTool(entries, PositionConstants.EAST, false, 5);
		}
		
		/**
		 * Init the label direct edit manager.
		 * This method should be called when a Direct Edit request is performed.
		 */
		protected void initLabelEditManager() {
			if(manager==null) {
				// locator for the cell editor (on the name label)
				CellEditorLocator locator = new LabelCellEditorLocator(getNameLabel());

				// defining how properties are modified in the model
				PropertyAccessor accessor = new PropertyAccessor() {
					public String getPropertyName() {
						return "Name";
					}					
					public String getValue() {
						if(isElementImport()){
							return getElementImport().getAlias();
						}
						return getUmlElement().getName();
					}
					public void setValue(String value) {
						if(isElementImport()){
							getElementImport().setAlias(value);
						}
						else{getUmlElement().setName(value);}  
					}
				};
				// defines the controler: link between model and view
				ILabelControler labelControler = new LabelControler(getNameLabel(), accessor);

				// creates the editing manager.
				manager = new LabelDirectEditManager(this, locator, labelControler);
			}
		}
}
